/**
 * @file order_server.cpp
 * @brief 订单服务器的实现文件
 * 
 * @details 该文件实现了OrderServer类的方法，包括构造函数、析构函数、
 * 启动和停止方法等。OrderServer负责管理客户端连接、接收客户端请求
 * 并将其转发给匹配引擎，以及将匹配引擎的响应发送回客户端。
 * 
 * @author 原作者
 * @date 2023
 */

#include "order_server.h"

namespace Exchange {
  /**
   * @brief OrderServer类的构造函数
   * 
   * @details 初始化订单服务器，设置客户端请求和响应队列，配置网络接口和端口。
   * 同时初始化序列号管理和客户端连接映射，并设置TCP服务器的回调函数。
   * 
   * @param client_requests 客户端请求无锁队列指针，用于将请求转发给匹配引擎
   * @param client_responses 客户端响应无锁队列指针，用于接收匹配引擎的响应
   * @param iface 网络接口名称
   * @param port 监听端口号
   */
  OrderServer::OrderServer(ClientRequestLFQueue *client_requests, ClientResponseLFQueue *client_responses, const std::string &iface, int port)
      : iface_(iface), port_(port), outgoing_responses_(client_responses), logger_("exchange_order_server.log"),
        tcp_server_(logger_), fifo_sequencer_(client_requests, &logger_) {
    // 初始化序列号管理，所有客户端的序列号从1开始
    cid_next_outgoing_seq_num_.fill(1);
    cid_next_exp_seq_num_.fill(1);
    // 初始化客户端连接映射为空
    cid_tcp_socket_.fill(nullptr);

    // 设置TCP服务器的接收数据回调函数
    tcp_server_.recv_callback_ = [this](auto socket, auto rx_time) { recvCallback(socket, rx_time); };
    // 设置TCP服务器的接收完成回调函数
    tcp_server_.recv_finished_callback_ = [this]() { recvFinishedCallback(); };
  }

  /**
   * @brief OrderServer类的析构函数
   * 
   * @details 停止订单服务器并等待资源释放。
   * 调用stop()方法停止订单服务器的运行，然后等待1秒以确保资源得到正确释放。
   */
  OrderServer::~OrderServer() {
    // 停止订单服务器
    stop();

    // 等待1秒以确保资源得到正确释放
    using namespace std::literals::chrono_literals;
    std::this_thread::sleep_for(1s);
  }

  /**
   * @brief 启动订单服务器
   * 
   * @details 启动订单服务器的主线程，开始监听指定的网络接口和端口，
   * 等待客户端连接并处理请求。
   * 该方法首先设置run_标志为true，然后启动TCP服务器并创建一个新线程来运行主循环。
   * 
   * @return void
   */
  auto OrderServer::start() -> void {
    // 设置运行标志为true
    run_ = true;
    // 启动TCP服务器，开始监听指定的网络接口和端口
    tcp_server_.listen(iface_, port_);

    // 创建并启动一个新线程来运行订单服务器的主循环
    ASSERT(Common::createAndStartThread(-1, "Exchange/OrderServer", [this]() { run(); }) != nullptr, "Failed to start OrderServer thread.");
  }

  /**
   * @brief 停止订单服务器
   * 
   * @details 通过设置run_标志为false，使订单服务器的主线程退出循环并结束运行。
   * 该方法仅设置标志，不会等待线程结束，因此在析构函数中还需要额外的等待时间。
   * 
   * @return void
   */
  auto OrderServer::stop() -> void {
    // 设置运行标志为false，使主循环退出
    run_ = false;
  }
}
